説明
バグレポート
画面からデータを返す
場合によっては、新しい画面からデータを返したい場合があります。 たとえば、ユーザーに 2 つのオプションを表示する新しい画面をプッシュするとします。 ユーザーがオプションをタップしたとき、最初の画面に通知したい ユーザーの選択内容を変更して、その情報に基づいて行動できるようにします。
これを行うには、Navigator.pop()
次の手順を使用する方法:
- ホーム画面を定義する
- 選択画面を起動するボタンを追加します。
- 2つのボタンで選択画面を表示します
- ボタンをタップすると選択画面を閉じます
- 選択した状態でホーム画面にスナックバーを表示します
1. ホーム画面を定義する
ホーム画面にはボタンが表示されます。タップすると、 選択画面が起動します。
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Returning Data Demo'),
),
// Create the SelectionButton widget in the next step.
body: const Center(
child: SelectionButton(),
),
);
}
}
2. 選択画面を起動するボタンを追加します。
ここで、次の処理を行う SelectionButton を作成します。
- タップするとSelectionScreenを起動します。
- SelectionScreen が結果を返すのを待ちます。
class SelectionButton extends StatefulWidget {
const SelectionButton({super.key});
@override
State<SelectionButton> createState() => _SelectionButtonState();
}
class _SelectionButtonState extends State<SelectionButton> {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: const Text('Pick an option, any option!'),
);
}
Future<void> _navigateAndDisplaySelection(BuildContext context) async {
// Navigator.push returns a Future that completes after calling
// Navigator.pop on the Selection Screen.
final result = await Navigator.push(
context,
// Create the SelectionScreen in the next step.
MaterialPageRoute(builder: (context) => const SelectionScreen()),
);
}
}
3. 2つのボタンで選択画面を表示する
次に、2 つのボタンを含む選択画面を作成します。 ユーザーがボタンをタップすると、 そのアプリは選択画面を閉じてホームに戻ります 画面ではどのボタンがタップされたかがわかります。
このステップでは UI を定義します。 次のステップでは、データを返すコードを追加します。
class SelectionScreen extends StatelessWidget {
const SelectionScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Pick an option'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () {
// Pop here with "Yep"...
},
child: const Text('Yep!'),
),
),
Padding(
padding: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () {
// Pop here with "Nope"...
},
child: const Text('Nope.'),
),
)
],
),
),
);
}
}
4. ボタンをタップしたら選択画面を閉じます
さて、更新してくださいonPressed()
両方のボタンのコールバック。
データを最初の画面に戻すには、
使用Navigator.pop()
方法、
これはオプションの 2 番目の引数を受け入れます。result
。
結果はすべてFuture
選択ボタンで。
はいボタン
ElevatedButton(
onPressed: () {
// Close the screen and return "Yep!" as the result.
Navigator.pop(context, 'Yep!');
},
child: const Text('Yep!'),
)
いいえボタン
ElevatedButton(
onPressed: () {
// Close the screen and return "Nope." as the result.
Navigator.pop(context, 'Nope.');
},
child: const Text('Nope.'),
)
5. ホーム画面に選択したスナックバーを表示します。
選択画面を起動して結果を待っているところです。 返された情報を使って何かをしたいと思うでしょう。
この場合、次のコマンドを使用して結果を表示するスナックバーを表示します。_navigateAndDisplaySelection()
のメソッドSelectionButton
:
// A method that launches the SelectionScreen and awaits the result from
// Navigator.pop.
Future<void> _navigateAndDisplaySelection(BuildContext context) async {
// Navigator.push returns a Future that completes after calling
// Navigator.pop on the Selection Screen.
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SelectionScreen()),
);
// When a BuildContext is used from a StatefulWidget, the mounted property
// must be checked after an asynchronous gap.
if (!mounted) return;
// After the Selection Screen returns a result, hide any previous snackbars
// and show the new result.
ScaffoldMessenger.of(context)
..removeCurrentSnackBar()
..showSnackBar(SnackBar(content: Text('$result')));
}
インタラクティブな例
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
title: 'Returning Data',
home: HomeScreen(),
),
);
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Returning Data Demo'),
),
body: const Center(
child: SelectionButton(),
),
);
}
}
class SelectionButton extends StatefulWidget {
const SelectionButton({super.key});
@override
State<SelectionButton> createState() => _SelectionButtonState();
}
class _SelectionButtonState extends State<SelectionButton> {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: const Text('Pick an option, any option!'),
);
}
// A method that launches the SelectionScreen and awaits the result from
// Navigator.pop.
Future<void> _navigateAndDisplaySelection(BuildContext context) async {
// Navigator.push returns a Future that completes after calling
// Navigator.pop on the Selection Screen.
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SelectionScreen()),
);
// When a BuildContext is used from a StatefulWidget, the mounted property
// must be checked after an asynchronous gap.
if (!mounted) return;
// After the Selection Screen returns a result, hide any previous snackbars
// and show the new result.
ScaffoldMessenger.of(context)
..removeCurrentSnackBar()
..showSnackBar(SnackBar(content: Text('$result')));
}
}
class SelectionScreen extends StatelessWidget {
const SelectionScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Pick an option'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () {
// Close the screen and return "Yep!" as the result.
Navigator.pop(context, 'Yep!');
},
child: const Text('Yep!'),
),
),
Padding(
padding: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () {
// Close the screen and return "Nope." as the result.
Navigator.pop(context, 'Nope.');
},
child: const Text('Nope.'),
),
)
],
),
),
);
}
}